import os
import logging
from flask import Flask, request, jsonify, render_template
import tensorflow as tf
import numpy as np
import cv2

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

app = Flask(__name__)

# 模型加载
try:
    model = tf.keras.models.load_model('E:/pythoncode/GenderRecognition-master/best_weights.weights.h5')
    logger.info("模型加载成功")
except Exception as e:
    logger.error(f"模型加载失败: {str(e)}")
    model = None


# 预处理函数
def preprocess_image(image_path):
    try:
        # 读取图像
        img = cv2.imread(image_path)
        if img is None:
            raise ValueError("无法读取图像")

        # 归一化处理
        img = img / 255.0

        # 调整大小
        img = cv2.resize(img, (100, 100))

        # 添加批次维度
        img = np.expand_dims(img, axis=0)

        return img
    except Exception as e:
        logger.error(f"图像预处理失败: {str(e)}")
        raise


# 首页路由
@app.route('/')
def index():
    return render_template('t.html')


# 定义预测接口
@app.route('/predict', methods=['POST'])
def predict():
    # 检查模型是否加载
    if model is None:
        return jsonify({
            'status': 'error',
            'error': '模型未加载，请检查模型路径和文件'
        }), 500

    # 检查是否有文件上传
    if 'image' not in request.files:
        return jsonify({
            'status': 'error',
            'error': '未提供图像文件',
            'expected_form_data': {'image': '上传的图像文件'}
        }), 400

    file = request.files['image']

    # 检查文件是否有名称
    if file.filename == '':
        return jsonify({
            'status': 'error',
            'error': '空文件名'
        }), 400

    # 检查文件类型
    allowed_extensions = {'png', 'jpg', 'jpeg'}
    if '.' not in file.filename or file.filename.rsplit('.', 1)[1].lower() not in allowed_extensions:
        return jsonify({
            'status': 'error',
            'error': '不支持的文件类型',
            'supported_formats': list(allowed_extensions)
        }), 400

    # 保存临时文件
    img_path = "temp.jpg"
    file.save(img_path)

    try:
        # 预处理图片
        processed_img = preprocess_image(img_path)

        # 预测
        predictions = model.predict(processed_img, verbose=0)
        result = np.argmax(predictions, axis=1)[0]

        # 将NumPy数据类型转换为Python原生类型
        predicted_label = int(result)
        confidences = [float(c) for c in predictions[0]]

        # 构建响应
        gender_labels = ['male', 'female']
        gender = gender_labels[predicted_label]
        confidence = confidences[predicted_label]

        return jsonify({
            'status': 'success',
            'predicted_label': predicted_label,
            'confidences': confidences,
            'gender': gender,
            'confidence': confidence
        })

    except Exception as e:
        logger.error(f"预测过程出错: {str(e)}")
        return jsonify({
            'status': 'error',
            'error': '预测过程中发生错误',
            'details': str(e)
        }), 500

    finally:
        # 清理临时文件
        if os.path.exists(img_path):
            os.remove(img_path)
            logger.debug("临时文件已删除")


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)